﻿namespace RockPaperScissors.Web
{
    using System;
    using System.Web.Security;
    using System.Web.UI;
    using GravityWorks.RockPaperScissors.Toolkit;
    using RockPaperScissors.Core;
    using RockPaperScissors.DataModel;
    
    public partial class Compete : Page
    {
        private Record m_firstTeamRecord = new Record();
        private Record m_secondTeamRecord = new Record();
        public static string BOT_PATH;// @"C:\Code\GravityWorks\GravityWorks.Compete\RockPaperScissors\RockPaperScissors.Web\bots\";
        private const int MATCH_STARTING_NUMBER = 1;
        
        protected void Page_Load(object sender, EventArgs e)
        {
            BOT_PATH = Server.MapPath(@"..\bots\");
            if (!Page.IsPostBack)
                txtRound.Text = SettingsHelper.GetRoundNumber().ToString();

            if (Membership.GetUser().UserName.ToLower() != "administrator")
                Response.Redirect("~/default.aspx");

            if (!Page.IsPostBack)
                LoadTeamsToSelect();
        }

        protected void btnCompete_Click(object sender, EventArgs e)
        {
            StartMatch(SettingsHelper.GetRoundNumber(), ddlTeamOne.SelectedValue, ddlTeamTwo.SelectedValue);
            this.Master.AddMessage("Finished processing match.", Message.Styles.Note);
        }

        protected void btnSaveRound_Click(object sender, EventArgs e)
        {
            int roundNumber = Convert.ToInt32(txtRound.Text);
            SettingsHelper.SetRoundNumber(roundNumber);
        }

        private void LoadTeamsToSelect()
        {
            MembershipUserCollection teams = Membership.GetAllUsers();

            ddlTeamOne.DataSource = teams;
            ddlTeamOne.DataTextField = "username";
            ddlTeamTwo.DataValueField = "username";
            ddlTeamOne.DataBind();

            ddlTeamTwo.DataSource = teams;
            ddlTeamTwo.DataTextField = "username";
            ddlTeamTwo.DataValueField = "username";
            ddlTeamTwo.DataBind();
        }

        private static void SaveToDatabase(ContestMatch contestMatch)
        {
            DataModel.RockPaperScissors context = new DataModel.RockPaperScissors();
            Match match = new Match();

            match.Round = contestMatch.Round;
            match.MatchNumber = contestMatch.MatchNumber;
            match.TeamName1 = contestMatch.TeamName1;
            match.TeamName2 = contestMatch.TeamName2;
            match.Team1Move = Enum.GetName(typeof(MoveType), contestMatch.Team1Move);
            match.Team2Move = Enum.GetName(typeof(MoveType), contestMatch.Team2Move);
            match.Team1Record = contestMatch.Team1Record;
            match.Team2Record = contestMatch.Team2Record;
            match.Winner = contestMatch.Winner;

            context.AddToMatchs(match);
            context.SaveChanges();
        }

        private void SaveRoundWinnerToDatabase(int round, string firstTeamName, string secondTeamName)
        {
            ContestMatch matchWinner = new ContestMatch();

            matchWinner.TeamName1 = firstTeamName;
            matchWinner.Team1Move = MoveType.None;
            matchWinner.Team2Move = MoveType.None;
            matchWinner.Round = round;
            matchWinner.MatchNumber = 9999;
            matchWinner.TeamName2 = secondTeamName;

            if (m_firstTeamRecord.Wins == CompeteHelper.BEST_OF)
                matchWinner.Winner = string.Format("{0} wins the round", firstTeamName);

            if (m_secondTeamRecord.Wins == CompeteHelper.BEST_OF)
                matchWinner.Winner = string.Format("{0} wins the round", secondTeamName);

            if (m_secondTeamRecord.Ties == CompeteHelper.MAX_MATCH_TIES)
            {
                if (m_firstTeamRecord.Wins > m_secondTeamRecord.Wins)
                    matchWinner.Winner = string.Format("{0} wins the round", firstTeamName);
                else if (m_firstTeamRecord.Wins < m_secondTeamRecord.Wins)
                    matchWinner.Winner = string.Format("{0} wins the round", secondTeamName);
                else
                    matchWinner.Winner = "Tie!! Real Rock paper scissors to end the round!";
            }

            matchWinner.Team1Record = string.Format("{0}-{1}-{2}", m_firstTeamRecord.Wins, m_firstTeamRecord.Losses, m_firstTeamRecord.Ties);
            matchWinner.Team2Record = string.Format("{0}-{1}-{2}", m_secondTeamRecord.Wins, m_secondTeamRecord.Losses, m_secondTeamRecord.Ties);
            SaveToDatabase(matchWinner);
        }

        private void StartMatch(int round, string firstTeamName, string secondTeamName)
        {
            int matchNumber = MATCH_STARTING_NUMBER;
            GameLog gameLog = new GameLog();
            string firstTeamPath = string.Format(@"{0}{1}\{2}\bot.dll", BOT_PATH, firstTeamName, round);
            string secondTeamPath = string.Format(@"{0}{1}\{2}\bot.dll", BOT_PATH, secondTeamName, round);

            RuleSet rules = CompeteHelper.GetRuleSetForMatch(round);

            // have round winner?
            while (CompeteHelper.HaveRoundWinner(m_firstTeamRecord, m_secondTeamRecord) == false)
            {
                string winner = string.Empty;
                ContestMatch contestMatch = new ContestMatch();

                MoveType firstTeamResult = CompeteHelper.ProcessPlayer(firstTeamName, firstTeamPath, gameLog, rules, round);
                MoveType secondTeamResult = CompeteHelper.ProcessPlayer(secondTeamName, secondTeamPath, gameLog, rules, round);

                MatchResult result = CompeteHelper.CalculateWinner(firstTeamName, firstTeamResult, secondTeamName, secondTeamResult, rules, gameLog);

                UpdateTeamRecords(firstTeamName, result);

                contestMatch = CompeteHelper.BuildContestMatch(round, firstTeamName, secondTeamName, matchNumber,
                    firstTeamResult, secondTeamResult, result, m_firstTeamRecord, m_secondTeamRecord);

                gameLog.Log.Add(contestMatch);

                SaveToDatabase(contestMatch);

                System.Threading.Thread.Sleep(9000);
                matchNumber++;
            }

            SaveRoundWinnerToDatabase(round, firstTeamName, secondTeamName);
        }

        private void UpdateTeamRecords(string firstTeamName, MatchResult result)
        {
            if (result.IsTie)
            {
                m_firstTeamRecord.Ties++;
                m_secondTeamRecord.Ties++;
            }
            else
            {
                if (result.WinnerTeamName == firstTeamName)
                {
                    m_firstTeamRecord.Wins++;
                    m_secondTeamRecord.Losses++;
                }
                else
                {
                    m_firstTeamRecord.Losses++;
                    m_secondTeamRecord.Wins++;
                }
            }
        }
    }
}